#include "../test_helpers.h"
#include "MessageProducer.h"
#include <spdlog/spdlog.h>
#include "MessageConsumer.h"
#include "MessageDispatcher.h"
#include "../../handlers/TradeSignalHandler.h"
#include "../../handlers/APIRequestHandler.h"
#include <gtest/gtest.h>
#include <atomic>
#include <thread>

using namespace MessageFramework;
using namespace MessageFramework::Test;

class EndToEndTest : public RedisTestBase {
protected:
    std::string streamName;
    std::string consumerGroup;

    void SetUp() override {
        RedisTestBase::SetUp();
        streamName = testStreamPrefix + "_stream";
        consumerGroup = testStreamPrefix + "_group";
    }
};

// ==================== 基础端到端测试 ====================

TEST_F(EndToEndTest, SimpleProducerConsumer) {
    // 创建生产者
    MessageProducer::Config producerConfig;
    producerConfig.publisherId = "TestProducer";
    producerConfig.secretKey = "test-secret-key-32bytes-long!!!";
    producerConfig.autoSign = true;

    MessageProducer producer(redisPool, producerConfig);

    // 创建消费者
    MessageConsumer::Config consumerConfig;
    consumerConfig.streamName = streamName;
    consumerConfig.consumerGroup = consumerGroup;
    consumerConfig.consumerId = "TestConsumer";
    consumerConfig.autoCreateGroup = true;

    auto dispatcher = std::make_shared<MessageDispatcher>();
    MessageDispatcher::Config dispatcherConfig;
    dispatcherConfig.secretKey = "test-secret-key-32bytes-long!!!";
    dispatcherConfig.verifySignature = true;
    dispatcher->setConfig(dispatcherConfig);

    // 注册Handler
    std::atomic<int> messageCount(0);
    std::string receivedBody;

    auto handler = std::make_shared<MockHandler>("TestMessage");
    dispatcher->registerHandler("TestMessage", handler);

    MessageConsumer consumer(redisPool, consumerConfig, dispatcher);
    consumer.start();

    // 发送消息
    std::string body = "{\"test\":\"data\"}";
    std::string streamId = producer.send(streamName, "TestMessage", body);
    EXPECT_FALSE(streamId.empty());

    // 等待消息被消费
    bool received = TestHelpers::waitFor([&]() {
        return handler->getCallCount() > 0;
    }, 5000);

    EXPECT_TRUE(received);
    EXPECT_EQ(handler->getCallCount(), 1);

    // 停止消费者
    consumer.stop();
}

// ==================== 多消息测试 ====================

TEST_F(EndToEndTest, MultipleMessages) {
    MessageProducer::Config producerConfig;
    producerConfig.publisherId = "TestProducer";
    producerConfig.secretKey = "test-secret-key-32bytes-long!!!";

    MessageProducer producer(redisPool, producerConfig);

    MessageConsumer::Config consumerConfig;
    consumerConfig.streamName = streamName;
    consumerConfig.consumerGroup = consumerGroup;
    consumerConfig.consumerId = "TestConsumer";

    auto dispatcher = std::make_shared<MessageDispatcher>();
    MessageDispatcher::Config dispatcherConfig;
    dispatcherConfig.secretKey = "test-secret-key-32bytes-long!!!";
    dispatcher->setConfig(dispatcherConfig);

    auto handler = std::make_shared<MockHandler>("TestMessage");
    dispatcher->registerHandler("TestMessage", handler);

    MessageConsumer consumer(redisPool, consumerConfig, dispatcher);
    consumer.start();

    // 发送10条消息
    const int messageCount = 10;
    for (int i = 0; i < messageCount; ++i) {
        std::string body = "{\"index\":" + std::to_string(i) + "}";
        producer.send(streamName, "TestMessage", body);
    }

    // 等待所有消息被消费
    bool received = TestHelpers::waitFor([&]() {
        return handler->getCallCount() >= messageCount;
    }, 10000);

    EXPECT_TRUE(received);
    EXPECT_EQ(handler->getCallCount(), messageCount);

    consumer.stop();
}

// ==================== 加密消息测试 ====================

TEST_F(EndToEndTest, EncryptedMessages) {
    std::string encryptionKey = EncryptionHelper::generateKey();

    // 生产者启用加密
    MessageProducer::Config producerConfig;
    producerConfig.publisherId = "TestProducer";
    producerConfig.secretKey = "test-secret-key-32bytes-long!!!";
    producerConfig.encryptionKey = encryptionKey;
    producerConfig.autoSign = true;
    producerConfig.autoEncrypt = true;

    MessageProducer producer(redisPool, producerConfig);

    // 消费者启用解密
    MessageConsumer::Config consumerConfig;
    consumerConfig.streamName = streamName;
    consumerConfig.consumerGroup = consumerGroup;
    consumerConfig.consumerId = "TestConsumer";

    auto dispatcher = std::make_shared<MessageDispatcher>();
    MessageDispatcher::Config dispatcherConfig;
    dispatcherConfig.secretKey = "test-secret-key-32bytes-long!!!";
    dispatcherConfig.encryptionKey = encryptionKey;
    dispatcherConfig.verifySignature = true;
    dispatcherConfig.autoDecrypt = true;
    dispatcher->setConfig(dispatcherConfig);

    auto handler = std::make_shared<MockHandler>("TestMessage");
    dispatcher->registerHandler("TestMessage", handler);

    MessageConsumer consumer(redisPool, consumerConfig, dispatcher);
    consumer.start();

    // 发送加密消息
    std::string plaintext = "{\"secret\":\"data\"}";
    producer.send(streamName, "TestMessage", plaintext);

    // 等待消息被解密并处理
    bool received = TestHelpers::waitFor([&]() {
        return handler->getCallCount() > 0;
    }, 5000);

    EXPECT_TRUE(received);
    EXPECT_EQ(handler->getCallCount(), 1);

    // 验证解密后的消息体
    Message lastMsg = handler->getLastMessage();
    EXPECT_EQ(lastMsg.body, plaintext);

    consumer.stop();
}

// ==================== TradeSignalHandler测试 ====================

TEST_F(EndToEndTest, TradeSignalHandler) {
    MessageProducer::Config producerConfig;
    producerConfig.publisherId = "StrategyEngine";
    producerConfig.secretKey = "test-secret-key-32bytes-long!!!";

    MessageProducer producer(redisPool, producerConfig);

    MessageConsumer::Config consumerConfig;
    consumerConfig.streamName = streamName;
    consumerConfig.consumerGroup = consumerGroup;
    consumerConfig.consumerId = "TraderManager";

    auto dispatcher = std::make_shared<MessageDispatcher>();
    MessageDispatcher::Config dispatcherConfig;
    dispatcherConfig.secretKey = "test-secret-key-32bytes-long!!!";
    dispatcher->setConfig(dispatcherConfig);

    // 注册TradeSignalHandler
    std::atomic<bool> signalReceived(false);
    TradingSignalBody receivedSignal;

    auto handler = std::make_shared<TradeSignalHandler>();
    handler->setCallback([&](const TradingSignalBody& signal,
                             const MessageHeader& header) -> int {
        receivedSignal = signal;
        signalReceived = true;
        return 0;
    });

    dispatcher->registerHandler("TradeSignal", handler);

    MessageConsumer consumer(redisPool, consumerConfig, dispatcher);
    consumer.start();

    // 发送交易信号
    TradingSignalBody signal;
    std::strcpy(signal.instrumentId, "rb2501");
    std::strcpy(signal.direction, "BUY");
    std::strcpy(signal.offsetFlag, "OPEN");
    signal.price = 4000.0;
    signal.volume = 1;
    std::strcpy(signal.orderType, "LIMIT");
    std::strcpy(signal.strategyId, "TestStrategy");

    producer.send(streamName, "TradeSignal", signal.toJson());

    // 等待信号被处理
    bool received = TestHelpers::waitFor([&]() {
        return signalReceived.load();
    }, 5000);

    EXPECT_TRUE(received);
    EXPECT_STREQ(receivedSignal.instrumentId, "rb2501");
    EXPECT_STREQ(receivedSignal.direction, "BUY");
    EXPECT_EQ(receivedSignal.price, 4000.0);
    EXPECT_EQ(receivedSignal.volume, 1);

    consumer.stop();
}

// ==================== 请求-响应测试 ====================

TEST_F(EndToEndTest, RequestResponse) {
    std::string requestStream = streamName + "_requests";
    std::string responseStream = streamName + "_responses";

    // 创建请求生产者
    MessageProducer::Config producerConfig;
    producerConfig.publisherId = "TraderAPI";
    producerConfig.secretKey = "test-secret-key-32bytes-long!!!";

    MessageProducer requestProducer(redisPool, producerConfig);

    // 创建响应生产者
    MessageProducer::Config responseProducerConfig;
    responseProducerConfig.publisherId = "TraderManager";
    responseProducerConfig.secretKey = "test-secret-key-32bytes-long!!!";

    auto responseProducer = std::make_shared<MessageProducer>(redisPool, responseProducerConfig);

    // 创建请求消费者
    MessageConsumer::Config consumerConfig;
    consumerConfig.streamName = requestStream;
    consumerConfig.consumerGroup = consumerGroup;
    consumerConfig.consumerId = "TraderManager";

    auto dispatcher = std::make_shared<MessageDispatcher>();
    MessageDispatcher::Config dispatcherConfig;
    dispatcherConfig.secretKey = "test-secret-key-32bytes-long!!!";
    dispatcher->setConfig(dispatcherConfig);

    // 注册APIRequestHandler
    auto handler = std::make_shared<APIRequestHandler>();
    handler->setProducer(responseProducer);
    handler->setCallback([](const APIRequestBody& request,
                            const MessageHeader& header) -> APIResponseBody {
        APIResponseBody response;
        response.code = 0;
        std::strcpy(response.message, "Success");
        std::strcpy(response.data, "{\"balance\":100000}");
        return response;
    });

    dispatcher->registerHandler("APIRequest", handler);

    MessageConsumer consumer(redisPool, consumerConfig, dispatcher);
    consumer.start();

    // 发送API请求
    APIRequestBody request;
    std::strcpy(request.requestType, "QUERY_ACCOUNT");
    std::strcpy(request.userId, "11440");

    std::string requestId = requestProducer.sendRequest(
        requestStream,
        "APIRequest",
        request.toJson(),
        responseStream,
        "TraderManager"
    );

    EXPECT_FALSE(requestId.empty());

    // 等待响应被生成
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // 读取响应（这里简化处理，实际应该用Consumer）
    //     RedisConnection* conn = redisPool->getConnection();
    //     auto messages = conn->xrange(responseStream, "-", "+", 10);
    // 
    //     EXPECT_GT(messages.size(), 0);
    // 
    //     redisPool->returnConnection(conn);
    consumer.stop();
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
